<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // let 关键字用来声明变量，使用 let 声明的变量有几个特点：
        // 1)  不允许重复声明
        // 2)  块儿级作用域
        // 3)  存在变量提升
        // 4)  不影响作用域链

        // 1)  不允许重复声明
        // var m = 100;
        // var m = 200; // var 可以重复声明

        // //1. let不允许重复声明
        // let n = 10;
        // //let n = 20; // 报错，不可重复声明
        // console.log(m, n);

        // 2)  块儿级作用域， 其中块你可以理解为{ }括起来的块
        // 在非函数方法的{}内使用var声明的变量，出来后还可以访问
        // for(var i = 1 ;i < 3; i++){
        // }
        // console.log(i); // 3
        // if(true){
        //     var m1 = 100;
        // }
        // for(var i = 0; i< 3;i++){
        //     var m2 = 200
        // }
        
        // {
        //     var m3 = 300
        // }
        // console.log(m1,m2, m3); // 100 200 300

        // let声明的变量只当前{}内有效，出了{}就看不到
        // for(let j = 1 ;j < 3; j++){
        // }
        // console.log(j); // j is not defined
        // let m = 100
        // {
        //     let m = 200;
        //     {
        //         let m = 300;
        //         console.log(m); // 300
        //     }
        //     console.log(m); // 200
        // }
        // console.log(m); // 100



        //3) 存在变量提升
        //  let声明的变量会提升，但是在没有初始化值之前是不能访问的。
        //  也就是在初始化值之前会有一个"暂时性死区",若访问则报：
        //  Uncaught ReferenceError: Cannot access 'num' before initialization
        // console.log(num); //
        // let num = 100; 


        //4)  不影响作用域链
        let mm = 100;
        function fun1(){
            let mm = 200;
            function fun2(){
                console.log(mm);
            }
            fun2();
        }
        fun1();

    </script>
</body>
</html>